<!doctype html>

<html>
<head>
  <link rel="shortcut icon" href="static/images/favicon.ico" type="image/x-icon">
  <title>sanitizer.js (Closure Library API Documentation - JavaScript)</title>
  <link rel="stylesheet" href="static/css/base.css">
  <link rel="stylesheet" href="static/css/doc.css">
  <link rel="stylesheet" href="static/css/sidetree.css">
  <link rel="stylesheet" href="static/css/prettify.css">

  <script>
     var _staticFilePath = "static/";
     var _typeTreeName = "goog";
     var _fileTreeName = "Source";
  </script>

  <script src="static/js/doc.js">
  </script>


  <meta charset="utf8">
</head>

<body onload="grokdoc.onLoad();">

<div id="header">
  <div class="g-section g-tpl-50-50 g-split">
    <div class="g-unit g-first">
      <a id="logo" href="index.html">Closure Library API Documentation</a>
    </div>

    <div class="g-unit">
      <div class="g-c">
        <strong>Go to class or file:</strong>
        <input type="text" id="ac">
      </div>
    </div>
  </div>
</div>

<div class="clear"></div>

<h2><a href="local_closure_goog_labs_html_sanitizer.js.html">sanitizer.js</a></h2>

<pre class="prettyprint lang-js">
<a name="line1"></a>// Copyright 2014 The Closure Library Authors. All Rights Reserved.
<a name="line2"></a>//
<a name="line3"></a>// Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
<a name="line4"></a>// you may not use this file except in compliance with the License.
<a name="line5"></a>// You may obtain a copy of the License at
<a name="line6"></a>//
<a name="line7"></a>//      http://www.apache.org/licenses/LICENSE-2.0
<a name="line8"></a>//
<a name="line9"></a>// Unless required by applicable law or agreed to in writing, software
<a name="line10"></a>// distributed under the License is distributed on an &quot;AS-IS&quot; BASIS,
<a name="line11"></a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a name="line12"></a>// See the License for the specific language governing permissions and
<a name="line13"></a>// limitations under the License.
<a name="line14"></a>
<a name="line15"></a>
<a name="line16"></a>/**
<a name="line17"></a> * @fileoverview
<a name="line18"></a> * An HTML sanitizer that takes untrusted HTML snippets and produces
<a name="line19"></a> * safe HTML by filtering/rewriting tags and attributes that contain
<a name="line20"></a> * high-privilege instructions.
<a name="line21"></a> */
<a name="line22"></a>
<a name="line23"></a>
<a name="line24"></a>goog.provide(&#39;goog.labs.html.Sanitizer&#39;);
<a name="line25"></a>
<a name="line26"></a>goog.require(&#39;goog.asserts&#39;);
<a name="line27"></a>goog.require(&#39;goog.html.SafeUrl&#39;);
<a name="line28"></a>goog.require(&#39;goog.labs.html.attributeRewriterPresubmitWorkaround&#39;);
<a name="line29"></a>goog.require(&#39;goog.labs.html.scrubber&#39;);
<a name="line30"></a>goog.require(&#39;goog.object&#39;);
<a name="line31"></a>goog.require(&#39;goog.string&#39;);
<a name="line32"></a>
<a name="line33"></a>
<a name="line34"></a>
<a name="line35"></a>/**
<a name="line36"></a> * A sanitizer that converts untrusted, messy HTML into more regular HTML
<a name="line37"></a> * that cannot abuse high-authority constructs like the ability to execute
<a name="line38"></a> * arbitrary JavaScript.
<a name="line39"></a> * @constructor
<a name="line40"></a> */
<a name="line41"></a>goog.labs.html.Sanitizer = function() {
<a name="line42"></a>  /**
<a name="line43"></a>   * Maps the lower-case names of allowed elements to attribute white-lists.
<a name="line44"></a>   * An attribute white-list maps lower-case attribute names to functions
<a name="line45"></a>   * from values to values or undefined to disallow.
<a name="line46"></a>   *
<a name="line47"></a>   * The special element name {@code &quot;*&quot;} contains a white-list of attributes
<a name="line48"></a>   * allowed on any tag, which is useful for attributes like {@code title} and
<a name="line49"></a>   * {@code id} which are widely available with element-agnostic meanings.
<a name="line50"></a>   * It should not be used for attributes like {@code type} whose meaning
<a name="line51"></a>   * differs based on the element on which it appears:
<a name="line52"></a>   * e.g. {@code &lt;input type=text&gt;} vs {@code &lt;style type=text/css&gt;}.
<a name="line53"></a>   *
<a name="line54"></a>   * @type {!Object.&lt;string, !Object.&lt;string, goog.labs.html.AttributeRewriter&gt;&gt;}
<a name="line55"></a>   * @private
<a name="line56"></a>   */
<a name="line57"></a>  this.whitelist_ = goog.labs.html.Sanitizer.createBlankObject_();
<a name="line58"></a>  this.whitelist_[&#39;*&#39;] = goog.labs.html.Sanitizer.createBlankObject_();
<a name="line59"></a>
<a name="line60"></a>  // To use the sanitizer, we build inputs for the scrubber.
<a name="line61"></a>  // These inputs are invalidated by changes to the policy, so we (re)build them
<a name="line62"></a>  // lazily.
<a name="line63"></a>
<a name="line64"></a>  /**
<a name="line65"></a>   * Maps element names to {@code true} so the scrubber does not have to do
<a name="line66"></a>   * own property checks for every tag filtered.
<a name="line67"></a>   *
<a name="line68"></a>   * Built lazily and invalidated when the white-list is modified.
<a name="line69"></a>   *
<a name="line70"></a>   * @type {Object.&lt;string, boolean&gt;}
<a name="line71"></a>   * @private
<a name="line72"></a>   */
<a name="line73"></a>  this.allowedElementSet_ = null;
<a name="line74"></a>};
<a name="line75"></a>
<a name="line76"></a>
<a name="line77"></a>// TODO(user): Should the return type be goog.html.SafeHtml?
<a name="line78"></a>// If we receive a safe HTML string as input, should we simply rebalance
<a name="line79"></a>// tags?
<a name="line80"></a>/**
<a name="line81"></a> * Yields a string of safe HTML that contains all and only the safe
<a name="line82"></a> * text-nodes and elements in the input.
<a name="line83"></a> *
<a name="line84"></a> * &lt;p&gt;
<a name="line85"></a> * For the purposes of this function, &quot;safe&quot; is defined thus:
<a name="line86"></a> * &lt;ul&gt;
<a name="line87"></a> *   &lt;li&gt;Contains only elements explicitly allowed via {@code this.allow*}.
<a name="line88"></a> *   &lt;li&gt;Contains only attributes explicitly allowed via {@code this.allow*}
<a name="line89"></a> *       and having had all relevant transformations applied.
<a name="line90"></a> *   &lt;li&gt;Contains an end tag for all and only non-void open tags.
<a name="line91"></a> *   &lt;li&gt;Tags nest per XHTML rules.
<a name="line92"></a> *   &lt;li&gt;Tags do not nest beyond a finite but fairly large level.
<a name="line93"></a> * &lt;/ul&gt;
<a name="line94"></a> *
<a name="line95"></a> * @param {!string} unsafeHtml A string of HTML which need not originate with
<a name="line96"></a> *    a trusted source.
<a name="line97"></a> * @return {!string} A string of HTML that contains only tags and attributes
<a name="line98"></a> *    explicitly allowed by this sanitizer, and with end tags for all and only
<a name="line99"></a> *    non-void elements.
<a name="line100"></a> */
<a name="line101"></a>goog.labs.html.Sanitizer.prototype.sanitize = function(unsafeHtml) {
<a name="line102"></a>  var unsafeHtmlString = &#39;&#39; + unsafeHtml;
<a name="line103"></a>
<a name="line104"></a>  /**
<a name="line105"></a>   * @type {!Object.&lt;string, !Object.&lt;string, goog.labs.html.AttributeRewriter&gt;&gt;}
<a name="line106"></a>   */
<a name="line107"></a>  var whitelist = this.whitelist_;
<a name="line108"></a>  if (!this.allowedElementSet_) {
<a name="line109"></a>    this.allowedElementSet_ = goog.object.createSet(
<a name="line110"></a>        // This can lead to &#39;*&#39; in the allowed element set, but the scrubber
<a name="line111"></a>        // will not parse &quot;&lt;*&quot; as a tag beginning.
<a name="line112"></a>        goog.object.getKeys(whitelist));
<a name="line113"></a>  }
<a name="line114"></a>
<a name="line115"></a>  return goog.labs.html.scrubber.scrub(
<a name="line116"></a>      this.allowedElementSet_, whitelist, unsafeHtmlString);
<a name="line117"></a>};
<a name="line118"></a>
<a name="line119"></a>
<a name="line120"></a>/**
<a name="line121"></a> * Adds the element names to the white-list of elements that are allowed
<a name="line122"></a> * in the safe HTML output.
<a name="line123"></a> * &lt;p&gt;
<a name="line124"></a> * Allowing elements does not, by itself, allow any attributes on
<a name="line125"></a> * those elements.
<a name="line126"></a> *
<a name="line127"></a> * @param {...!string} var_args element names that should be allowed in the
<a name="line128"></a> *     safe HTML output.
<a name="line129"></a> * @return {!goog.labs.html.Sanitizer} {@code this}.
<a name="line130"></a> */
<a name="line131"></a>goog.labs.html.Sanitizer.prototype.allowElements = function(var_args) {
<a name="line132"></a>  this.allowedElementSet_ = null;  // Invalidate.
<a name="line133"></a>  var whitelist = this.whitelist_;
<a name="line134"></a>  for (var i = 0; i &lt; arguments.length; ++i) {
<a name="line135"></a>    var elementName = arguments[i].toLowerCase();
<a name="line136"></a>
<a name="line137"></a>    goog.asserts.assert(
<a name="line138"></a>        goog.labs.html.Sanitizer.isValidHtmlName_(elementName), elementName);
<a name="line139"></a>
<a name="line140"></a>    if (!Object.prototype.hasOwnProperty.call(whitelist, elementName)) {
<a name="line141"></a>      whitelist[elementName] = goog.labs.html.Sanitizer.createBlankObject_();
<a name="line142"></a>    }
<a name="line143"></a>  }
<a name="line144"></a>  return this;
<a name="line145"></a>};
<a name="line146"></a>
<a name="line147"></a>
<a name="line148"></a>/**
<a name="line149"></a> * Allows in the sanitized output
<a name="line150"></a> * &lt;tt&gt;&amp;lt;&lt;i&gt;element&lt;/i&gt; &lt;i&gt;attr&lt;/i&gt;=&quot;...&quot;&amp;gt;&lt;/tt&gt;
<a name="line151"></a> * when &lt;i&gt;element&lt;/i&gt; is in {@code elementNames} and
<a name="line152"></a> * &lt;i&gt;attrNames&lt;/i&gt; is in {@code attrNames}.
<a name="line153"></a> *
<a name="line154"></a> * If specified, {@code opt_valueXform} is a function that takes the
<a name="line155"></a> * HTML-entity-decoded attribute value, and can choose to disallow the
<a name="line156"></a> * attribute by returning {@code null} or substitute a new value
<a name="line157"></a> * by returning a string with the new value.
<a name="line158"></a> *
<a name="line159"></a> * @param {!Array.&lt;string&gt;|string} elementNames names (or name) on which the
<a name="line160"></a> *     attributes are allowed.
<a name="line161"></a> *
<a name="line162"></a> *     Element names should be allowed via {@code allowElements(...)} prior
<a name="line163"></a> *     to white-listing attributes.
<a name="line164"></a> *
<a name="line165"></a> *     The special element name {@code &quot;*&quot;} has the same meaning as in CSS
<a name="line166"></a> *     selectors: it can be used to white-list attributes like {@code title}
<a name="line167"></a> *     and {@code id} which are widely available with element-agnostic
<a name="line168"></a> *     meanings.
<a name="line169"></a> *
<a name="line170"></a> *     It should not be used for attributes like {@code type} whose meaning
<a name="line171"></a> *     differs based on the element on which it appears:
<a name="line172"></a> *     e.g. {@code &lt;input type=text&gt;} vs {@code &lt;style type=text/css&gt;}.
<a name="line173"></a> *
<a name="line174"></a> * @param {!Array.&lt;string&gt;|string} attrNames names (or name) of the attribute
<a name="line175"></a> *     that should be allowed.
<a name="line176"></a> *
<a name="line177"></a> * @param {goog.labs.html.AttributeRewriter=} opt_rewriteValue A function
<a name="line178"></a> *     that receives the HTML-entity-decoded attribute value and can return
<a name="line179"></a> *     {@code null} to disallow the attribute entirely or the value for the
<a name="line180"></a> *     attribute as a string.
<a name="line181"></a> *     &lt;p&gt;
<a name="line182"></a> *     The default is the identity function ({@code function(x){return x}}),
<a name="line183"></a> *     and the value rewriter is composed with an attribute specific handler:
<a name="line184"></a> *     &lt;table&gt;
<a name="line185"></a> *      &lt;tr&gt;
<a name="line186"></a> *        &lt;th&gt;href, src&lt;/th&gt;
<a name="line187"></a> *        &lt;td&gt;Requires that the value be an absolute URL with a protocol in
<a name="line188"></a> *            (http, https, mailto) or a protocol relative URL.
<a name="line189"></a> *      &lt;/tr&gt;
<a name="line190"></a> *     &lt;/table&gt;
<a name="line191"></a> *
<a name="line192"></a> * @return {!goog.labs.html.Sanitizer} {@code this}.
<a name="line193"></a> */
<a name="line194"></a>goog.labs.html.Sanitizer.prototype.allowAttributes =
<a name="line195"></a>    function(elementNames, attrNames, opt_rewriteValue) {
<a name="line196"></a>  if (!goog.isArray(elementNames)) {
<a name="line197"></a>    elementNames = [elementNames];
<a name="line198"></a>  }
<a name="line199"></a>  if (!goog.isArray(attrNames)) {
<a name="line200"></a>    attrNames = [attrNames];
<a name="line201"></a>  }
<a name="line202"></a>  goog.asserts.assert(
<a name="line203"></a>      !opt_rewriteValue || &#39;function&#39; === typeof opt_rewriteValue,
<a name="line204"></a>      &#39;opt_rewriteValue should be a function&#39;);
<a name="line205"></a>
<a name="line206"></a>  var whitelist = this.whitelist_;
<a name="line207"></a>  for (var ei = 0; ei &lt; elementNames.length; ++ei) {
<a name="line208"></a>    var elementName = elementNames[ei].toLowerCase();
<a name="line209"></a>    goog.asserts.assert(
<a name="line210"></a>        goog.labs.html.Sanitizer.isValidHtmlName_(elementName) ||
<a name="line211"></a>        &#39;*&#39; === elementName,
<a name="line212"></a>        elementName);
<a name="line213"></a>    // If the element has not been white-listed then panic.
<a name="line214"></a>    // TODO(user): allow allow{Elements,Attributes} to be called in any
<a name="line215"></a>    // order if someone needs it.
<a name="line216"></a>    if (!Object.prototype.hasOwnProperty.call(whitelist, elementName)) {
<a name="line217"></a>      throw new Error(elementName);
<a name="line218"></a>    }
<a name="line219"></a>    var attrWhitelist = whitelist[elementName];
<a name="line220"></a>    for (var ai = 0, an = attrNames.length; ai &lt; an; ++ai) {
<a name="line221"></a>      var attrName = attrNames[ai].toLowerCase();
<a name="line222"></a>      goog.asserts.assert(
<a name="line223"></a>          goog.labs.html.Sanitizer.isValidHtmlName_(attrName), attrName);
<a name="line224"></a>
<a name="line225"></a>      // If the value has already been allowed, then chain the rewriters
<a name="line226"></a>      // so that both white-listers concerns are met.
<a name="line227"></a>      // We do not use the default rewriter here since it should have
<a name="line228"></a>      // been introduced by the call that created the initial white-list
<a name="line229"></a>      // entry.
<a name="line230"></a>      attrWhitelist[attrName] = goog.labs.html.Sanitizer.chain_(
<a name="line231"></a>          opt_rewriteValue || goog.labs.html.Sanitizer.valueIdentity_,
<a name="line232"></a>          Object.prototype.hasOwnProperty.call(attrWhitelist, attrName) ?
<a name="line233"></a>              attrWhitelist[attrName] :
<a name="line234"></a>              goog.labs.html.Sanitizer.defaultRewriterForAttr_(attrName));
<a name="line235"></a>    }
<a name="line236"></a>  }
<a name="line237"></a>  return this;
<a name="line238"></a>};
<a name="line239"></a>
<a name="line240"></a>
<a name="line241"></a>/**
<a name="line242"></a> * A new object that is as blank as possible.
<a name="line243"></a> *
<a name="line244"></a> * Using {@code Object.create} to create an object with
<a name="line245"></a> * no prototype speeds up whitelist access since there&#39;s fewer prototypes
<a name="line246"></a> * to fall-back to for a common case where an element is not in the
<a name="line247"></a> * white-list, and reduces the chance of confusing a member of
<a name="line248"></a> * {@code Object.prototype} with a whitelist entry.
<a name="line249"></a> *
<a name="line250"></a> * @return {!Object.&lt;string, ?&gt;} a reference to a newly allocated object that
<a name="line251"></a> *    does not alias any reference that existed prior.
<a name="line252"></a> * @private
<a name="line253"></a> */
<a name="line254"></a>goog.labs.html.Sanitizer.createBlankObject_ = function() {
<a name="line255"></a>  return (Object.create || Object)(null);
<a name="line256"></a>};
<a name="line257"></a>
<a name="line258"></a>
<a name="line259"></a>/**
<a name="line260"></a> * HTML element and attribute names may be almost arbitrary strings, but the
<a name="line261"></a> * sanitizer is more restrictive as to what can be white-listed.
<a name="line262"></a> *
<a name="line263"></a> * Since HTML is case-insensitive, only lower-case identifiers composed of
<a name="line264"></a> * ASCII letters, digits, and select punctuation are allowed.
<a name="line265"></a> *
<a name="line266"></a> * @param {string} name
<a name="line267"></a> * @return {boolean} true iff name is a valid white-list key.
<a name="line268"></a> * @private
<a name="line269"></a> */
<a name="line270"></a>goog.labs.html.Sanitizer.isValidHtmlName_ = function(name) {
<a name="line271"></a>  return &#39;string&#39; === typeof name &amp;&amp;  // Names must be strings.
<a name="line272"></a>      // Names must be lower-case and ASCII identifier chars only.
<a name="line273"></a>      /^[a-z][a-z0-9\-:]*$/.test(name);
<a name="line274"></a>};
<a name="line275"></a>
<a name="line276"></a>
<a name="line277"></a>/**
<a name="line278"></a> * @param  {goog.labs.html.AttributeValue} x
<a name="line279"></a> * @return {goog.labs.html.AttributeValue}
<a name="line280"></a> * @private
<a name="line281"></a> */
<a name="line282"></a>goog.labs.html.Sanitizer.valueIdentity_ = function(x) {
<a name="line283"></a>  return x;
<a name="line284"></a>};
<a name="line285"></a>
<a name="line286"></a>
<a name="line287"></a>/**
<a name="line288"></a> * @param  {goog.labs.html.AttributeValue} x
<a name="line289"></a> * @return {null}
<a name="line290"></a> * @private
<a name="line291"></a> */
<a name="line292"></a>goog.labs.html.Sanitizer.disallow_ = function(x) {
<a name="line293"></a>  return null;
<a name="line294"></a>};
<a name="line295"></a>
<a name="line296"></a>
<a name="line297"></a>/**
<a name="line298"></a> * Chains attribute rewriters.
<a name="line299"></a> *
<a name="line300"></a> * @param  {goog.labs.html.AttributeRewriter} f
<a name="line301"></a> * @param  {goog.labs.html.AttributeRewriter} g
<a name="line302"></a> * @return {goog.labs.html.AttributeRewriter}
<a name="line303"></a> *      a function that return g(f(x)) or null if f(x) is null.
<a name="line304"></a> * @private
<a name="line305"></a> */
<a name="line306"></a>goog.labs.html.Sanitizer.chain_ = function(f, g) {
<a name="line307"></a>  // Sometimes white-listing code ends up allowing things multiple times.
<a name="line308"></a>  if (f === goog.labs.html.Sanitizer.valueIdentity_) {
<a name="line309"></a>    return g;
<a name="line310"></a>  }
<a name="line311"></a>  if (g === goog.labs.html.Sanitizer.valueIdentity_) {
<a name="line312"></a>    return f;
<a name="line313"></a>  }
<a name="line314"></a>  // If someone tries to white-list a really problematic value, we reject
<a name="line315"></a>  // it by returning disallow_.  Disallow it quickly.
<a name="line316"></a>  if (f === goog.labs.html.Sanitizer.disallow_) {
<a name="line317"></a>    return f;
<a name="line318"></a>  }
<a name="line319"></a>  if (g === goog.labs.html.Sanitizer.disallow_) {
<a name="line320"></a>    return g;
<a name="line321"></a>  }
<a name="line322"></a>  return (
<a name="line323"></a>      /**
<a name="line324"></a>       * @param {goog.labs.html.AttributeValue} x
<a name="line325"></a>       * @return {goog.labs.html.AttributeValue}
<a name="line326"></a>       */
<a name="line327"></a>      function(x) {
<a name="line328"></a>        var y = f(x);
<a name="line329"></a>        return y != null ? g(y) : null;
<a name="line330"></a>      });
<a name="line331"></a>};
<a name="line332"></a>
<a name="line333"></a>
<a name="line334"></a>/**
<a name="line335"></a> * Given an attribute name, returns a value rewriter that enforces some
<a name="line336"></a> * minimal safety properties.
<a name="line337"></a> *
<a name="line338"></a> * &lt;p&gt;
<a name="line339"></a> * For url atributes, it checks that any protocol is on a safe set that
<a name="line340"></a> * doesn&#39;t allow script execution.
<a name="line341"></a> * &lt;p&gt;
<a name="line342"></a> * It also blanket disallows CSS and event handler attributes.
<a name="line343"></a> *
<a name="line344"></a> * @param  {string} attrName lower-cased attribute name.
<a name="line345"></a> * @return {goog.labs.html.AttributeRewriter}
<a name="line346"></a> * @private
<a name="line347"></a> */
<a name="line348"></a>goog.labs.html.Sanitizer.defaultRewriterForAttr_ = function(attrName) {
<a name="line349"></a>  if (&#39;href&#39; === attrName || &#39;src&#39; === attrName) {
<a name="line350"></a>    return goog.labs.html.Sanitizer.checkUrl_;
<a name="line351"></a>  } else if (&#39;style&#39; === attrName || &#39;on&#39; === attrName.substr(0, 2)) {
<a name="line352"></a>    // TODO(user): delegate to a CSS sanitizer if one is available.
<a name="line353"></a>    return goog.labs.html.Sanitizer.disallow_;
<a name="line354"></a>  }
<a name="line355"></a>  return goog.labs.html.Sanitizer.valueIdentity_;
<a name="line356"></a>};
<a name="line357"></a>
<a name="line358"></a>
<a name="line359"></a>/**
<a name="line360"></a> * Applied automatically to URL attributes to check that they are safe as per
<a name="line361"></a> * {@link SafeUrl}.
<a name="line362"></a> *
<a name="line363"></a> * @param {goog.labs.html.AttributeValue} attrValue a decoded attribute value.
<a name="line364"></a> * @return {goog.html.SafeUrl | null} a URL that is equivalent to the
<a name="line365"></a> *    input or {@code null} if the input is not a safe URL.
<a name="line366"></a> * @private
<a name="line367"></a> */
<a name="line368"></a>goog.labs.html.Sanitizer.checkUrl_ = function(attrValue) {
<a name="line369"></a>  if (attrValue == null) {
<a name="line370"></a>    return null;
<a name="line371"></a>  }
<a name="line372"></a>  /** @type {!goog.html.SafeUrl} */
<a name="line373"></a>  var safeUrl;
<a name="line374"></a>  if (attrValue instanceof goog.html.SafeUrl) {
<a name="line375"></a>    safeUrl = /** @type {!goog.html.SafeUrl} */ (attrValue);
<a name="line376"></a>  } else {
<a name="line377"></a>    if (typeof attrValue === &#39;string&#39;) {
<a name="line378"></a>      // Whitespace at the ends of URL-valued attributes in HTML is ignored.
<a name="line379"></a>      attrValue = goog.string.trim(/** @type {string} */ (attrValue));
<a name="line380"></a>    }
<a name="line381"></a>    safeUrl = goog.html.SafeUrl.sanitize(
<a name="line382"></a>        /** @type {!goog.string.TypedString | string} */ (attrValue));
<a name="line383"></a>  }
<a name="line384"></a>  if (goog.html.SafeUrl.unwrap(safeUrl) == goog.html.SafeUrl.INNOCUOUS_STRING) {
<a name="line385"></a>    return null;
<a name="line386"></a>  } else {
<a name="line387"></a>    return safeUrl;
<a name="line388"></a>  }
<a name="line389"></a>};
<a name="line390"></a>
<a name="line391"></a>
<a name="line392"></a>goog.labs.html.attributeRewriterPresubmitWorkaround();
</pre>


</body>
</html>
